import inspect
import dis
from collections import UserList
def my_gen():
    yield 1
    name="caoyx"
    yield 2
    age = 40
    return "hello"

def main():
    g = my_gen()

    print(dis.dis(g))

    print(g.gi_frame.f_lasti)
    print(g.gi_frame.f_locals)
    next(g)
    print(g.gi_frame.f_lasti)
    print(g.gi_frame.f_locals)
    next(g)
    print(g.gi_frame.f_lasti)
    print(g.gi_frame.f_locals)


def test_yield():
    print("AAA")
    yield "tiger"
    print("BBB")
    yield "rose"
    print("CCC")

def test():
    t = test_yield()
    for v in t:
        print(v)
        print("-----------------------")


def test_send():
    def my_gen():
        #这里有两个作用，1 生成url 给外部   2 接收调用者传入的参数对html赋值
        html = yield "https://www.baidu.com"
        print(html)
        yield "OK"

    gen = my_gen()
    url = next(gen)
    print(gen.send("<html>百度</html>"))
    print(next(gen))


def test_close():
    def my_gen():
        try:
            yield "http://www.baidu.com"
        except GeneratorExit as e:
            raise e
            #print('---->',e)
        yield "ok"
        yield "JK"
        return "hello"
    g = my_gen()
    print(next(g))
    g.close()
    print("&&&&&&")
    next(g)

def test_throw():
    def my_gen():
        try:
            yield "http://www.baidu.com"
        except Exception as e:
            print(e)
        print("我继续执行")
        yield "2"
        yield "3"
        return "hello"
    g = my_gen()
    print(next(g))
    g.throw(Exception,'人为抛出')
    print(next(g))


def test_yield_from():
    #自定义 chain 的实现
    def my_chain(*args,**kwargs):
        for item in args:
            yield from item
            # yield from 等价于下面的代码
            # for v in item:
            #     yield v

    from itertools import chain
    books = ["增值税","财务会计实战","申报简介"]
    taxs = {"10101":"增值税一般纳税人","29034":"财产行为税"}
    #通过chain 会逐个迭代里面的可迭代对象
    for v in chain(books,taxs):
        print(v)
    for v in my_chain(books,taxs):
        print(v)

def test_yield_from2():
    def g1(iter):
        yield iter
    def g2(iter):
        yield from iter
    for v in g1(range(5)):
        print(v)     #  range(0, 5)
    for v in g2(range(5)):
        print(v)     #  0 1 2 3 4


def test_gen_state():
    import inspect
    def my_gen():
        yield "hello"
        return "world"
    g = my_gen()
    print(inspect.getgeneratorstate(g))
    next(g)
    print(inspect.getgeneratorstate(g))
    try:
        next(g)
    except StopIteration as e:
        pass
    print(inspect.getgeneratorstate(g))

if __name__ == '__main__':
    test_gen_state()
